package cache

import (
	storage "ozonTest/internal/dal/cache"
	"ozonTest/internal/domain/comments/model"
	model2 "ozonTest/internal/domain/posts/model"
	"testing"
	"time"
)

func TestCreateComment(t *testing.T) {
	// Создаем базу данных комментариев для тестирования
	db := &storage.Database{
		Comments: make(map[int]*model.Comment),
		Posts:    make(map[int]*model2.Post),
	}

	// Создаем репозиторий комментариев
	repo := NewCommentsRepo(db)

	// Создаем комментарий для тестирования
	comment := &model.Comment{
		ID:        1,
		PostID:    1,
		ParentID:  nil,
		Content:   "Test comment",
		CreatedAt: time.Now(),
	}

	// Вызываем функцию CreateComment
	err := repo.CreateComment(comment)
	if err != nil {
		t.Errorf("Error creating comment: %v", err)
	}

	// Проверяем, что комментарий был добавлен в базу данных
	if len(db.Comments) != 1 {
		t.Errorf("Expected 1 comment in the database, got %d", len(db.Comments))
	}

	// Проверяем, что содержимое комментария совпадает с ожидаемым
	createdComment, ok := db.Comments[1]
	if !ok {
		t.Error("Comment not found in the database")
	} else {
		if createdComment.Content != "Test comment" {
			t.Errorf("Expected content 'Test comment', got '%s'", createdComment.Content)
		}
	}
}

func TestCreateReply(t *testing.T) {
	db := &storage.Database{
		Comments: make(map[int]*model.Comment),
		Posts:    make(map[int]*model2.Post),
	}

	repo := NewCommentsRepo(db)

	parentComment := &model.Comment{
		ID:        1,
		PostID:    1,
		Content:   "Parent comment",
		CreatedAt: time.Now(),
	}
	db.Comments[parentComment.ID] = parentComment

	// Создаем ответ на комментарий
	reply := &model.Comment{
		PostID:  1,
		Content: "Reply to parent comment",
	}

	// Вызываем функцию CreateReply
	err := repo.CreateReply(parentComment.ID, reply)
	if err != nil {
		t.Errorf("Error creating reply: %v", err)
	}

	// Проверяем, что ответ был добавлен в базу данных
	if len(db.Comments) != 2 {
		t.Errorf("Expected 2 comments in the database, got %d", len(db.Comments))
	}

	// Проверяем, что ответ был правильно связан с родительским комментарием
	createdReply, ok := db.Comments[2]
	if !ok {
		t.Error("Reply not found in the database")
	} else {
		if createdReply.ParentID == nil || *createdReply.ParentID != parentComment.ID {
			t.Errorf("Expected ParentID %d, got %v", parentComment.ID, createdReply.ParentID)
		}
		if createdReply.Content != "Reply to parent comment" {
			t.Errorf("Expected content 'Reply to parent comment', got '%s'", createdReply.Content)
		}
	}
}

func TestGetComment(t *testing.T) {
	// Создаем базу данных для тестирования
	db := &storage.Database{
		Comments: make(map[int]*model.Comment),
		Posts:    make(map[int]*model2.Post),
	}

	repo := NewCommentsRepo(db)

	comment := &model.Comment{
		ID:        1,
		PostID:    1,
		Content:   "Test comment",
		CreatedAt: time.Now(),
	}
	db.Comments[comment.ID] = comment

	retrievedComment, err := repo.GetComment(comment.ID)
	if err != nil {
		t.Errorf("Error getting comment: %v", err)
	}

	if retrievedComment.ID != comment.ID {
		t.Errorf("Expected ID %d, got %d", comment.ID, retrievedComment.ID)
	}
	if retrievedComment.Content != comment.Content {
		t.Errorf("Expected content '%s', got '%s'", comment.Content, retrievedComment.Content)
	}
}

func TestGetAllComments(t *testing.T) {
	db := &storage.Database{
		Comments: make(map[int]*model.Comment),
		Posts:    make(map[int]*model2.Post),
	}

	repo := NewCommentsRepo(db)

	comments := []*model.Comment{
		{
			ID:        1,
			PostID:    1,
			Content:   "Comment 1",
			CreatedAt: time.Now(),
		},
		{
			ID:        2,
			PostID:    1,
			Content:   "Comment 2",
			CreatedAt: time.Now(),
		},
	}
	for _, comment := range comments {
		db.Comments[comment.ID] = comment
	}

	allComments, err := repo.GetAllComments()
	if err != nil {
		t.Errorf("Error getting all comments: %v", err)
	}

	if len(allComments) != len(comments) {
		t.Errorf("Expected %d comments, got %d", len(comments), len(allComments))
	}

	for i, comment := range allComments {
		if comment.ID != comments[i].ID {
			t.Errorf("Expected ID %d, got %d", comments[i].ID, comment.ID)
		}
		if comment.Content != comments[i].Content {
			t.Errorf("Expected content '%s', got '%s'", comments[i].Content, comment.Content)
		}
	}
}

func TestDeleteComment(t *testing.T) {
	db := &storage.Database{
		Comments: make(map[int]*model.Comment),
		Posts:    make(map[int]*model2.Post),
	}

	repo := NewCommentsRepo(db)

	comment := &model.Comment{
		ID:        1,
		PostID:    1,
		Content:   "Test comment",
		CreatedAt: time.Now(),
	}
	db.Comments[comment.ID] = comment

	err := repo.DeleteComment(comment.ID)
	if err != nil {
		t.Errorf("Error deleting comment: %v", err)
	}

	if _, exists := db.Comments[comment.ID]; exists {
		t.Error("Comment was not deleted from the database")
	}
}

func TestGetCommentsByPost(t *testing.T) {
	db := &storage.Database{
		Comments: make(map[int]*model.Comment),
		Posts:    make(map[int]*model2.Post),
	}

	repo := NewCommentsRepo(db)

	comments := []*model.Comment{
		{
			ID:        1,
			PostID:    1,
			Content:   "Comment 1",
			CreatedAt: time.Now(),
		},
		{
			ID:        2,
			PostID:    1,
			Content:   "Comment 2",
			CreatedAt: time.Now(),
		},
		{
			ID:        3,
			PostID:    2,
			Content:   "Comment 3",
			CreatedAt: time.Now(),
		},
	}
	for _, comment := range comments {
		db.Comments[comment.ID] = comment
	}

	postID := 1
	postComments, err := repo.GetCommentsByPost(postID)
	if err != nil {
		t.Errorf("Error getting comments by post: %v", err)
	}

	expectedComments := 2
	if len(postComments) != expectedComments {
		t.Errorf("Expected %d comments, got %d", expectedComments, len(postComments))
	}

	for _, comment := range postComments {
		if comment.PostID != postID {
			t.Errorf("Expected PostID %d, got %d", postID, comment.PostID)
		}
	}
}
